
package com.probiz.estoresa.catalog.web.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.servlet.ModelAndView;

import com.probiz.estore.Constants;
import com.probiz.estore.catalog.model.ProductCategoryFullyModel;
import com.probiz.estore.catalog.service.ProductCategoryManager;
import com.probiz.estore.common.model.catalog.ProductCategory;
import com.probiz.estore.common.model.product.Product;
import com.probiz.estore.common.model.sales.RecommendedType;
import com.probiz.estore.core.controller.GenericStoreAdminController;
import com.probiz.estore.core.exception.ApplicationException;
import com.probiz.estore.product.service.ProductTypeManager;
import com.probiz.estore.sales.model.RecommendedTypeSearchCriteria;
import com.probiz.estore.sales.service.AutoEvalRecommendationManager;
import com.probiz.estore.sales.service.RecommendedTypeManager;
import com.probiz.estore.webapp.util.RequestUtil;

public class ProductCategoryController extends
		GenericStoreAdminController<ProductCategory> {
	private ProductCategoryManager	productCategoryManager	= null;
	private ProductTypeManager productTypeManager =null;
	private RecommendedTypeManager recommendedTypeManager = null;
	private AutoEvalRecommendationManager autoEvalRecommendationManager = null;

	public void setProductCategoryManager(ProductCategoryManager productCategoryManager) {
		this.productCategoryManager = productCategoryManager;
	}

	
	public void setProductTypeManager(ProductTypeManager productTypeManager) {
		this.productTypeManager = productTypeManager;
	}

	
	public void setRecommendedTypeManager(
			RecommendedTypeManager recommendedTypeManager) {
		this.recommendedTypeManager = recommendedTypeManager;
	}

	
	public void setAutoEvalRecommendationManager(
			AutoEvalRecommendationManager autoEvalRecommendationManager) {
		this.autoEvalRecommendationManager = autoEvalRecommendationManager;
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.controller.GenericController#getEntityName(java.lang.Object)
	 */
	@Override
	protected String getEntityName(ProductCategory entity) {
		return entity.getProductCategoryName();
	}


	/*
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.controller.BaseController#initController()
	 */
	@Override
	protected void initController() throws Exception {
		mgr = productCategoryManager;
	}

	public ModelAndView defaultAction(HttpServletRequest request,
			HttpServletResponse response) {
		ModelAndView mv = new ModelAndView("catalog/productCategoryList");
		ProductCategory treeRoot = productCategoryManager.getById(1);
		Set<ProductCategory> categorySet = treeRoot.getChildren();
		List<ProductCategory> categoryList = new ArrayList<ProductCategory>();
		categoryList.addAll(categorySet);
		mv.addObject("categoryList", categoryList);
		mv.addObject("treeRoot", treeRoot);
		return mv;
	}
	
	/**
	 * 获取树节点，ajax方式
	 * @param request
	 * @param response
	 * @return
	 */
	public ModelAndView getTreeItems(HttpServletRequest request,HttpServletResponse response) {
		ModelAndView mv = new ModelAndView("/catalog/include/productCategoryTreeAjax");
		String categoryId = RequestUtil.getParameterNullSafe(request, "categoryId");
		ProductCategory parent = productCategoryManager.getById(Integer.valueOf(categoryId));
		Set<ProductCategory> categorySet = parent.getChildren();
		List<ProductCategory> categoryList = new ArrayList<ProductCategory>();
		categoryList.addAll(categorySet);
		mv.addObject("categoryList",categoryList);
		return mv;
		
	}

	/**
	 * 按categoryIds的顺序更新目录sortOrder
	 */
	public ModelAndView updateCategoriesSortOrder(HttpServletRequest request,
			HttpServletResponse response) {
		Integer[] categoryIds = RequestUtil.getIntegerArrayNullSafe(request,
				"categoryIds");
		// MethodUtils.invokeMethod(mgr, "updateCategoriesSortOrder", new
		// Object[]{categoryIds});
		productCategoryManager.updateCategoriesSortOrder(categoryIds);
		return null;
	}

	/**
	 * 按categoryId删除目录
	 */
	public ModelAndView delete(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		Integer categoryId = RequestUtil.getInteger(request, "categoryId");
		ProductCategory productCategory = productCategoryManager.getById(categoryId);
		Map<String, Object> data = productCategoryManager.deleteFully(productCategory);
		return getModelAndAjaxJsonView(data);

	}

	public ModelAndView edit(HttpServletRequest request,
			HttpServletResponse response) {
		ModelAndView mv = new ModelAndView("catalog/productCategoryForm");

		Integer categoryId = RequestUtil.getInteger(request, "categoryId");
		if (null != categoryId) {
			// case:编辑
			ProductCategory category = productCategoryManager
					.getById(categoryId);
			mv.addObject("category", category);
		} else {
			// case:新增
			Integer parentCategoryId = RequestUtil.getInteger(request,
					"parentCategoryId");
			ProductCategory parentCategory = productCategoryManager
					.getById(parentCategoryId);
			mv.addObject("parentCategory", parentCategory);
			ProductCategory category = new ProductCategory();
			category.setParent(parentCategory);
			mv.addObject("category", category);
		}
		mv.addObject("productTypeList", productTypeManager.listAll());
		
		//start:激活的关联推荐类型
		RecommendedTypeSearchCriteria recommendedTypeSearchCriteria = new RecommendedTypeSearchCriteria();
		recommendedTypeSearchCriteria.setStatus(Constants.FLAG_TRUE);
		recommendedTypeSearchCriteria.setIsApplyToProduct(Constants.FLAG_FALSE);
		List<RecommendedType> recommendedTypeList = recommendedTypeManager.getRecommendedTypesBySearchCriteria(recommendedTypeSearchCriteria);
		mv.addObject("recommendedTypeList", recommendedTypeList);
		//end:激活的关联推荐类型
		return mv;
	}

	public ModelAndView add(HttpServletRequest request,
			HttpServletResponse response) {
		return edit(request, response);
	}

	/**
	 * 前置绑定，避免验证错误
	 * 
	 * @param entity
	 *            实体
	 */
	private void bindReady(ProductCategory entity) {
		if (null == entity.getCategoryId()) {
            //case:新增
            entity.setSortOrder(ProductCategory.SORTORDER_DEFAULT_VALUE);
        }
	}

	/*
	 * 保存前的检验和赋值 
	 * (non-Javadoc)
	 * 
	 * @see com.probiz.estore.core.controller.GenericStoreAdminController#preSave(javax.servlet.http.HttpServletRequest,
	 *      java.lang.Object, org.springframework.validation.BindException)
	 */
	protected void preSave(HttpServletRequest request, ProductCategory entity,
			BindException errors) {
		// start:赋值dispalyFlag
		String[] displayFlagArray = RequestUtil.getParameterValuesNullSafe(request, "displayFlag");
		StringBuffer displayFlag = new StringBuffer();
		for(String flag : displayFlagArray){
			displayFlag.append(flag);
		}
		entity.setDisplayFlag(displayFlag.toString());
		// end:赋值dispalyFlag
	}

	public ModelAndView save(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

		// 取得Form对应的Model
		ProductCategory entity = formBackingObject(request);
		BindException errors = null;
		Map<String, Object> data = new HashMap<String, Object>();
		try {
			bindReady(entity);
			ServletRequestDataBinder binder = bindAndValidate(request, entity);
			errors = new BindException(binder.getBindingResult());
			// 传给子类的实现，后者可以继续验证和加入错误到errors
			preSave(request, entity, errors);
			if (!errors.hasErrors()) {// 里面如果出错应该抛出异常
				Map<String, Object> saveData = productCategoryManager
						.saveFully(getProductCategoryModel(request,entity, data));
				data.putAll(saveData);
			}
		} catch (ApplicationException e) {
			handleApplicationException(errors, e);
		}

		buildReturnInfo(data, entity, request);

		return getModelAndAjaxJsonView(data);
	}

	/**
	 * 加入返回参数
	 * 
	 * @param data
	 * @param product
	 * @param request
	 */
	private void buildReturnInfo(Map<String, Object> data,
			ProductCategory entity, HttpServletRequest request) {
		data.put("categoryId", entity.getCategoryId());
		data.put("categoryName", entity.getCategoryName());
		data.put("categoryCode", entity.getCategoryCode());
		data.put("depth", entity.getDepth());
		data.put("itemCount", entity.getItemCount());
		data.put("activeItemCount", entity.getActiveItemCount());

	}

	/**
	 * 构造目录模型，方便保存
	 * 
	 * @param entity
	 * @param data
	 * @return
	 */
	private ProductCategoryFullyModel getProductCategoryModel(HttpServletRequest request,ProductCategory entity, Map<String, Object> data) {
		ProductCategoryFullyModel model = new ProductCategoryFullyModel();
		model.setProductCategory(entity);
		
		// --------- start: 绑定推荐关联商品----------------
		String[] recommendedTypeIds = RequestUtil.getParameterValuesNullSafe(request, "recommendedTypeIds");
		String[] recommendedProductIds = RequestUtil.getParameterValuesNullSafe(request, "recommendedProductIds");
		model.setRecommendedTypeIds(recommendedTypeIds);
		model.setRecommendedProductIds(recommendedProductIds);
		// --------- end: 绑定推荐关联商品----------------
		
		return model;
	}
	
	
	/**
	 * 获得自动评估商品列表
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	public ModelAndView getAutoEvalProducts(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		
		Map<String, Object> data = new HashMap<String, Object>();
		Integer categoryId = RequestUtil.getInteger(request, "productCategoryId");
		Integer recommendedTypeId = RequestUtil.getInteger(request, "recommendedTypeId");
		RecommendedType recommendedType = recommendedTypeManager.getById(recommendedTypeId);
		List<Product> result = autoEvalRecommendationManager.getProductsByRuleCodeBySourceId(recommendedType.getRuleCode(), categoryId, 0, 5);
		JSONArray autoEvalProductArray = new JSONArray();
		for(Product product: result){
			JSONObject jsonProduct = new JSONObject();
			jsonProduct.put("id", product.getProductId());
			jsonProduct.put("name", product.getProductName());
			jsonProduct.put("imageUrl", product.getImageUrl());
			autoEvalProductArray.add(jsonProduct);
		}
		data.put("autoEvalProductArray", autoEvalProductArray);
		data.put("recommendedTypeId", recommendedTypeId);
		return getModelAndAjaxJsonView(data);
	}

}
